{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### sklearn中通用的方法们\n",
    "\n",
    "#### model.fit(训练集的数据，训练集的标签)  在训练集上训练模型\n",
    "\n",
    "#### model.predict(数据集（测试数据集或者是新的数据））  对输入数据做一个输出的预测\n",
    "\n",
    "#### model.score(训练集的数据，训练集的标签）计算的就是在训练集的得分（准确率）\n",
    "\n",
    "#### model.score(测试集的数据，测试集的标签）计算的就是在测试集的得分（准确率）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#scikit-learn\n",
    "#sklearn\n",
    "%matplotlib inline\n",
    "import matplotlib.pyplot as  plt\n",
    "import numpy as np\n",
    "x=np.array([1,2,3,4])  #x 代表房子的面积\n",
    "y=np.array([4,6,10,15])  # y 代表就是房子的售价\n",
    "#(1,4),(2,6),(3,10),(4,15)\n",
    "plt.scatter(x,y)   #画出x，y对应的散点图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LinearRegression\n",
    "from sklearn.metrics import mean_squared_error\n",
    "\n",
    "model=LinearRegression()#创建一个线性回归的模型\n",
    "x=x.reshape(-1,1)  #变化数据格式，使其符合sklearn对数据的格式要求\n",
    "y=y.reshape(-1,1)\n",
    "\n",
    "model.fit(x,y)  #利用现有数据训练模型\n",
    "print(model.intercept_)  #查看模型的截距参数\n",
    "print(model.coef_) #查看模型的系数，斜率\n",
    "\n",
    "train_score=model.score(x,y)  #计算模型在训练集上的得分\n",
    "mse=mean_squared_error(y,model.predict(x)) #model.predict(x) 以x为输入，经过模型的计算得到输出，mean_squared_error是计算均方根误差\n",
    "\n",
    "print(train_score)\n",
    "print(mse)\n",
    "\n",
    "plt.scatter(x,y)  #根据x和y画原始数据的散点图\n",
    "plt.plot(x,model.predict(x),'r-')   #画最终模型的线图，其中x是输入的x，y是模型预测的结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.externals import joblib\n",
    "joblib.dump(model,'LRModel.pkl')  #保存模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "z=np.array([6,7,8,9])\n",
    "z=z.reshape(-1,1)\n",
    "mymodel=joblib.load('LRModel.pkl')  #加载已经保存好的模型\n",
    "pred=mymodel.predict(z)  #用加载的模型对新数据z做预测\n",
    "pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "n_dots=200\n",
    "\n",
    "X=np.linspace(-2*np.pi,2*np.pi,n_dots)  #随机生成-2pi到2pi之间的200个点\n",
    "Y=np.sin(X)+0.2*np.random.rand(n_dots)-0.1   #生成符合正弦曲线的一部分点，但是适当增加噪声数据\n",
    "plt.figure(figsize=(12,6))  #设置图片的大小\n",
    "plt.scatter(X,Y)   #画出散点图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#处理样本数据的格式，选择线性回归模型，用样本数据训练模型，计算模型的得分和均方根误差，并最终画图\n",
    "X=X.reshape(-1,1)\n",
    "Y=Y.reshape(-1,1)\n",
    "\n",
    "model=LinearRegression()\n",
    "\n",
    "model.fit(X,Y)\n",
    "\n",
    "train_score=model.score(X,Y)\n",
    "mse = mean_squared_error(X,model.predict(X))  #预测的值与实际值之间的均方根误差\n",
    "\n",
    "print(train_score)\n",
    "print(mse)\n",
    "\n",
    "plt.scatter(X,Y)\n",
    "plt.plot(X,model.predict(X),'r-')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 上述模型训练的结果是欠拟合的。\n",
    "\n",
    "#### 欠拟合：模型不能很好的拟合现有数据，也不能预测新数据\n",
    "\n",
    "#### 欠拟合表明模型太简单，处理方法如下：\n",
    "\n",
    "#### 1， 增加有价值的特征\n",
    "\n",
    "#### 2，增加多项式特征  原有特征为 x1, x2，经过二阶多项式特征变换之后得到新增特征（ x1^2, x2^2, x1*x2）\n",
    "\n",
    "#### 增加多项式特征时使用 PolynomialFeatures(degree=integer, interaction_only=False, include_bias=True)\n",
    "\n",
    "##### degree 是多项式的阶， interaction_only这个参数如果为True，表示只有特征之间相互作用的项才会被选用，include_bias表示是否包含一个常量的截距"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import PolynomialFeatures\n",
    "from sklearn.pipeline import Pipeline\n",
    "\n",
    "def polynomial_model(degree=1):\n",
    "    polynomial_features=PolynomialFeatures(degree=degree,include_bias=False)  #多项式特征\n",
    "    linear_regression=LinearRegression(normalize=True) #线性回归的模型 normalize=True表示对输入数据做归一化处理\n",
    "    pipeline=Pipeline([('polynomial_features',polynomial_features),('linear_regression',linear_regression)])\n",
    "    #pipeline是一个管道，管道中放了一个多项式特征，一个线性回归模型。样本数据会先经过多项式特征，具备了更多的特征之后，会作为输入\n",
    "    #进入到线性回归模型中去训练模型\n",
    "    return pipeline\n",
    "\n",
    "degree=[2,3,5,10]\n",
    "results=[]\n",
    "\n",
    "for d in degree:\n",
    "    model=polynomial_model(d)  #生成阶数为d的多项式模型（d阶多项式特征+线性回归模型）\n",
    "    model.fit(X,Y)\n",
    "    train_score=model.score(X,Y)\n",
    "    mse=mean_squared_error(Y,model.predict(X))\n",
    "    results.append({'model':model})\n",
    "    print(\"degree: {}; train_score: {}; mean squared error: {}\".format(d,train_score,mse))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.figure(figsize=(12,6))\n",
    "for i,result in enumerate(results):\n",
    "    fig=plt.subplot(2,2,i+1)\n",
    "    plt.xlim(-8,8)  #设置x轴的取值\n",
    "    plt.scatter(X,Y,s=5,c='b',alpha=0.5)\n",
    "    plt.plot(X,result['model'].predict(X),'r-')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
